﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using BizElements.TemplateEngine;

namespace BizElements.Generator
{
    public partial class ComponentVariablesCtl : UserControl
    {
        string componentName;
        Dictionary<TemplateComponentVariableDefinition, Control> bindings = new Dictionary<TemplateComponentVariableDefinition, Control>();
        List<Pair<Control, string>> controlsAndInitialValues = new List<Pair<Control, string>>();

        public ComponentVariablesCtl()
        {
            InitializeComponent();
            this.UseNullInsteadOfDefaultValue = true;
        }

        private void ComponentVariablesCtl_Load(object sender, EventArgs e)
        {
            foreach (Pair<Control, string> ctlAndValue in this.controlsAndInitialValues)
                SetControlValue(ctlAndValue.Name, ctlAndValue.Value);
        }

        #region Initialize and create controls.

        public void SetComponentVariables(string componentName, IList<TemplateComponentVariableDefinition> componentVariableDefinitions, IEnumerable<Pair<string, string>> selectedValues)
        {
            this.componentName = componentName;
            CreateAllVariableControlsAndSetDefaults(componentVariableDefinitions, selectedValues);
            this.Text = componentName;
        }

        private void CreateAllVariableControlsAndSetDefaults(IList<TemplateComponentVariableDefinition> componentVariableDefinitions, IEnumerable<Pair<string, string>> selectedValues)
        {
            this.bindings = new Dictionary<TemplateComponentVariableDefinition, Control>();
            foreach (TemplateComponentVariableDefinition variable in componentVariableDefinitions)
            {
                Label lbl = new Label() { Text = variable.Description ?? variable.Name, Width = 190, AutoEllipsis = true };
                var nameAndVal = selectedValues.FirstOrDefault<Pair<string, string>>(val => val.Name == variable.Name);
                Control ctl = CreateBoundControl(variable);
                bindings[variable] = ctl;
                this.uiTable.Controls.Add(lbl);
                this.uiTable.Controls.Add(ctl);

                // Dynamicaly added combo boxes --> values can be set after load event.
                string selectedValue = (nameAndVal != null) ? nameAndVal.Value : variable.DefaultValue;
                this.controlsAndInitialValues.Add(new Pair<Control, string>(ctl, selectedValue));
            }
        }

        private Control CreateBoundControl(TemplateComponentVariableDefinition variable)
        {
            if (variable.AllowedValues != null && variable.AllowedValues.Length > 0)
            {
                ComboBox ddl = new ComboBox()
                {
                    ValueMember = "Value",
                    DisplayMember = "Name",
                    DropDownStyle = ComboBoxStyle.DropDownList,
                    Width = 390,
                    Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right
                };

                ddl.DataSource = variable.AllowedValues;
                return ddl;
            }
            else
            {
                return new TextBox()
                {
                    Width = 390,
                    Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right
                };
            }
        }

        private void SetControlValue(Control ctl, string selectedValue)
        {
            ListControl ddl = ctl as ListControl;
            if (ddl != null)
            {
                try { ddl.SelectedValue = selectedValue; }
                catch { ddl.SelectedIndex = 0; }
            }
            else
            {
                ctl.Text = selectedValue;
            }
        }

        #endregion

        public bool UseNullInsteadOfDefaultValue { get; set; }

        #region Return changes.

        public List<Triple<string, string, string>> ParseVariables()
        {
            List<Triple<string, string, string>> newValues = new List<Triple<string, string, string>>();
            foreach (KeyValuePair<TemplateComponentVariableDefinition, Control> varAndCtl in this.bindings)
            {
                TemplateComponentVariableDefinition var = varAndCtl.Key;
                Control ctl = varAndCtl.Value;
                string selectedValue = ParseVariable(ctl);
                if (this.UseNullInsteadOfDefaultValue && (selectedValue == var.DefaultValue))
                    selectedValue = null;

                newValues.Add(new Triple<string, string, string>(this.componentName, var.Name, selectedValue));
            }

            return newValues;
        }

        private static string ParseVariable(Control ctl)
        {
            string value;
            ListControl ddl = ctl as ListControl;
            if (ddl != null)
                value = Convert.ToString(ddl.SelectedValue);
            else
                value = ctl.Text.Trim();

            if (string.IsNullOrEmpty(value))
                value = null;

            return value;
        }

        #endregion
    }
}
